package com.bungarus.utils;

import org.apache.log4j.Logger;
import org.springframework.util.StringUtils;

import java.io.*;
import java.net.*;
import java.nio.charset.Charset;
import java.util.Enumeration;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

public class IPAddressUtils {
    private static Logger logger = Logger.getLogger(IPAddressUtils.class);
    /**
     * 多网卡场景获取真实IP
     *
     * @return InetAddress
     */
    public static InetAddress getLocalHostLANAddress() throws UnknownHostException {
        try {
            for(Enumeration<NetworkInterface> e = NetworkInterface.getNetworkInterfaces();e.hasMoreElements();) {
                NetworkInterface currentNetwork = e.nextElement();
                for(InterfaceAddress address : currentNetwork.getInterfaceAddresses()) {
                    if(currentNetwork.isLoopback() || !currentNetwork.isUp() || currentNetwork.isVirtual()) {
                        continue;
                    }
                    if(address.getAddress() instanceof Inet4Address) {
                        Inet4Address inet4Address = (Inet4Address)address.getAddress();
                        if(inet4Address.isSiteLocalAddress()) {
                            return inet4Address;
                        }
                    }
                }
            }
            return InetAddress.getLocalHost();
        } catch (SocketException | UnknownHostException e) {
            throw  new RuntimeException(e);
        }
    }

    public static String getLocalHostWANAddress() {
        logger.info("getting server WAN ip address.... ");
        String ipString = null;
        BufferedInputStream bis = null;
        BufferedReader br = null;
        try {
            String command = "curl ifconfig.me";
            Process process = Runtime.getRuntime().exec(command);
            bis = new BufferedInputStream(
                    process.getInputStream());
            br = new BufferedReader(new InputStreamReader(bis, Charset.forName("utf-8")));
            while((ipString = br.readLine())!= null){
                break;
            }
            logger.info("server WAN ip detected -> " + ipString);
            process.waitFor(10L, TimeUnit.SECONDS);
            if (process.exitValue() != 0) {
                System.out.println("error!");
            }
        }
        catch (Exception e){
            e.printStackTrace();
        }
        finally {
            try {
                if(null != bis)
                    bis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(null != br)
                    br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if(!ipCheck(ipString)){
            return null;
        }
        return ipString;
    }

    public static boolean ipCheck(String ipString) {
        if (ipString != null && !ipString.isEmpty()) {
            String regex = "([1-9]|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3}";
            if (ipString.matches(regex)) {
                return true;
            }
        }
        return false;
    }

    public static final class HostPortPair {
        public String host;
        public int port;

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            HostPortPair that = (HostPortPair) o;
            return port == that.port &&
                    Objects.equals(host, that.host);
        }

        @Override
        public int hashCode() {
            return ("" + host + port).hashCode() ;
        }

        @Override
        public String toString() {
            return "HostPortPair{" +
                    "host='" + host + '\'' +
                    ", port=" + port +
                    '}';
        }

        public HostPortPair copy() {
            HostPortPair copy = new HostPortPair();
            copy.host = this.host;
            copy.port = this.port;
            return copy;
        }
    }

    public static void main(String[] args){
        System.out.println(getLocalHostWANAddress());
    }
}